經過前幾天的介紹,我們已經更熟悉使用 Express 框架,
接下來我們需要實作才能學以致用,
今天開始我們會開始做一個小專案,來記錄我們每個人的書單列表。
首先第一步,就是做註冊和登入系統,
讓我們繼續看下去吧~
    <!-- public/views/index.ejs -->
    <!DOCTYPE html>
      <html lang="en">
      <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <link rel="stylesheet" href="/views/css/index.css">
        <title>首頁</title>
      </head>
        <!-- Header -->
        <%- include('header') %>
        <!-- Header -->
      <body>
        <main>
          <p><%= username %>'s book list  </p>
        </main>
        <!-- Footer -->
        <%- include('footer') %>
        <!-- Footer -->
      </body>
    </html>
    <!-- public/views/signIn.ejs -->
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>sign in</title>
      <link rel="stylesheet" href="/views/css/signIn.css"> <!-- 引入您的 CSS 文件 -->
    </head>
    <body>
        <!-- Header -->
        <%- include('header') %>
        <!-- Header -->
      <main>
        <!-- 註冊表單 -->
        <form action="/signIn" method="post"> 
          <label for="username">Username:</label>
          <input type="text" id="username" name="username" required>
          <br>
          <label for="password">Password:</label>
          <input type="password" id="password" name="password" required>
          <br>
          <button type="submit">Login</button>
          <div class="login-text">Already have an account?<a href="/login">Click here to log in.</a></div>
          <div>
            <% if (error) { %>
              <p><%= error %></p>
            <% } %>
          </div> 
        </form>
      </main>
        <!-- Footer -->
        <%- include('footer') %>
        <!-- Footer -->
    </body>
    </html>
    <!-- public/views/login.ejs -->
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Log in</title>
      <link rel="stylesheet" href="/views/css/login.css"> <!-- 引入您的 CSS 文件 -->
    </head>
    <body>
        <!-- Header -->
        <%- include('header') %>
        <!-- Header -->
      <main>
        <!-- 登入表單 -->
        <form action="/login" method="post"> 
          <label for="username">Username:</label>
          <input type="text" id="username" name="username" required>
          <br>
          <label for="password">Password:</label>
          <input type="password" id="password" name="password" required>
          <br>
          <button type="submit">Login</button>
          <div class="login-text">Don't have an account yet?<a href="./signIn">Click here to register.</a></div>
          <div>
            <% if (error) { %>
              <p><%= error %></p>
            <% } %>
          </div>      
        </form>
      </main>
        <!-- Footer -->
        <%- include('footer') %>
        <!-- Footer -->
    </body>
    </html>
login.ejs需要注意<form action="/login" method="post">的地方,
我們填完表單送出時,會打POST /login方法,
將username和password資料傳遞過來,
所以我們需要創一個POST /login的路由,來處理傳過來的登入表單資料。
因為我們需要記住使用者已經當入的狀態,
所以接下來會介紹 express-session 這個套件來將使用者資料儲存在 session。
在 app.js 檔案,載入 express-session 套件,並使用 app.use() 調用此套件。
    // app.js
    app.use(session({
      secret: 'your-secret-key', // 建議將此替換為實際的安全密鑰
      resave: false, // 是否每次都重新保存 session,預設為 true
      saveUninitialized: false, // 是否每次都重新產生 session,預設為 true
      cookie: { secure: false } // 建議在生產環境中將其設置為 true,以使用HTTPS
    }))
    app.use(router)
app.use(session())的 middleware 需要設置於app.use(router)之前,這樣執行router時才能取得session資訊。
因為我們每頁都要確認該使用者是否為登入狀態,可以新增一個 middleware 資料夾,並新增一個 auth.js 檔案,將我們判斷是否登入的 middleware 方法寫在這裡。
我們用 session 來判別是否該使用者的登入狀態,並且判斷 登入 / 未登入兩種狀況 →
一般都是儲存不太重要的資料作為判別,千萬不要把使用者密碼也存起來哦!
  ```jsx
      // middleware/auth.js
      function requireLogin(req, res, next) {
        if (req.session && req.session.user) {
          // 用戶已經登入,繼續執行下一個中間件或路由處理程序
          return next()
        } else {
          // 用戶未登入,重定向到登入頁面或其他處理方式
          return res.redirect('/login')
        }
      }
      module.exports =requireLogin
  ```
在今天設置的首頁和登入頁(index.ejs和login.ejs)加入 GET  方法,這樣瀏覽器輸入 localhost:3000/ 和localhost:3000/ login 才能 render 出 首頁和登入頁的畫面。
將 login和 signIn 模組化。
    // routes/modules/index.js
    router.get('/', requireLogin, (req, res) => {
      res.render('index', {'username': req.session.user})
    })
    // routes/modules/login.js
    router.get('/', (req, res) => {
      res.render('login')
    })
    // routes/modules/signIn.js
    router.get('/', (req, res) => {
      res.render('signIn')
    })
將兩個模組導入我們的 index.js
    // routes/index.js
    const express = require('express')
    const router = express.Router()
    const index = require('./modules/index')
    const login = require('./modules/login')
    const signIn = require('./modules/signIn')
    router.use('/', index)
    router.use('/login', login)
    router.use('/signIn', signIn)
還記得我們剛剛建立判斷是否登入的 middleware 嗎?
如果我們希望在一進首頁時就確認該使用者是否登入,所以我們就要在進到首頁路由前,判斷是否為登入狀態,如果沒有登入過就要導去登入頁。
    const requireLogin = require('../../middleware/auth') // 引入判斷是否登入的模組
    router.get('/', requireLogin, (req, res) => { // 在進入首頁時判斷是否為登入狀態
      res.render('index')
})
今天先介紹到這邊~
剩下我們明天再繼續介紹!